hvm_stts(v);
/* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( pt->enabled && pt->first_injected ) {
+ if ( pt->enabled && v->vcpu_id == pt->bind_vcpu && pt->first_injected ) {
if ( v->arch.hvm_vcpu.guest_time ) {
hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time);
v->arch.hvm_vcpu.guest_time = 0;
pit_init(v, cpu_khz);
rtc_init(v, RTC_PORT(0), RTC_IRQ);
pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS);
+
+ /* init guest tsc to start from 0 */
+ hvm_set_guest_time(v, 0);
}
void pic_irq_request(void *data, int level)
stop_timer (&pt->timer);
pt->enabled = 0;
}
+ pt->bind_vcpu = 0; /* timer interrupt delivered to BSP by default */
pt->pending_intr_nr = 0;
pt->first_injected = 0;
if (period < 900000) { /* < 0.9 ms */
struct periodic_time *pt =
&(v->domain->arch.hvm_domain.pl_time.periodic_tm);
- if ( pt->enabled && is_periodic_irq(v, vector, type) ) {
+ if ( pt->enabled && v->vcpu_id == pt->bind_vcpu
+ && is_periodic_irq(v, vector, type) ) {
if ( !pt->first_injected ) {
pt->pending_intr_nr = 0;
pt->last_plt_gtime = hvm_get_guest_time(v);
{
struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
- if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
+ if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu
+ && !v->arch.hvm_vcpu.guest_time ) {
v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
stop_timer(&(pt->timer));
}
error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
}
+/* Update CR3, CR0, CR4, GDT, LDT, TR */
static void vmx_do_launch(struct vcpu *v)
{
-/* Update CR3, CR0, CR4, GDT, LDT, TR */
unsigned int error = 0;
unsigned long cr0, cr4;
- if (v->vcpu_id == 0)
+ if ( v->vcpu_id == 0 )
hvm_setup_platform(v->domain);
+ else {
+ /* Sync AP's TSC with BSP's */
+ v->arch.hvm_vcpu.cache_tsc_offset =
+ v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
+ hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
+ }
__asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : );
__vmwrite(HOST_CR3, v->arch.cr3);
v->arch.schedule_tail = arch_vmx_do_resume;
-
- /* init guest tsc to start from 0 */
- hvm_set_guest_time(v, 0);
}
/*
{
struct periodic_time *pt=&v->domain->arch.hvm_domain.pl_time.periodic_tm;
- if ( pt->enabled && pt->first_injected && !v->arch.hvm_vcpu.guest_time ) {
+ if ( pt->enabled && pt->first_injected && v->vcpu_id == pt->bind_vcpu
+ && !v->arch.hvm_vcpu.guest_time ) {
v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v);
stop_timer(&(pt->timer));
}
switch (regs->ecx) {
case MSR_IA32_TIME_STAMP_COUNTER:
+ {
+ struct periodic_time *pt =
+ &(v->domain->arch.hvm_domain.pl_time.periodic_tm);
+ if ( pt->enabled && pt->first_injected
+ && v->vcpu_id == pt->bind_vcpu )
+ pt->first_injected = 0;
+ }
hvm_set_guest_time(v, msr_content);
break;
case MSR_IA32_SYSENTER_CS:
char one_shot; /* one shot time */
char irq;
char first_injected; /* flag to prevent shadow window */
+ u32 bind_vcpu; /* vcpu timer interrupt delivers to */
u32 pending_intr_nr; /* the couner for pending timer interrupts */
u32 period; /* frequency in ns */
u64 period_cycles; /* frequency in cpu cycles */